package com.zte.ao;

import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.confluence.spaces.Space;
import com.atlassian.confluence.user.ConfluenceUser;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import net.java.ao.DBParam;
import net.java.ao.Query;
import org.apache.log4j.Logger;

import javax.inject.Inject;
import java.sql.Timestamp;
import java.util.concurrent.TimeUnit;

@Scanned
public class ActiveObjectServiceImpl {
    private static final Logger LOG = Logger.getLogger(ActiveObjectServiceImpl.class);

    @ComponentImport
    private ActiveObjects fAo;

    @Inject
    public ActiveObjectServiceImpl(ActiveObjects ao) {
        this.fAo = ao;
        if (this.fAo == null) {
            throw new RuntimeException("Could not initialized with ActiveObjects");
        }
    }

    public AuditEntity createAuditEntity(OperationType type, AuditEventOutcome outcome, Space space, String relatedGroupName, String relatedUserName, ConfluenceUser adminUser, String summary, String comment) {
        AuditEntity e = (AuditEntity) this.fAo.create(AuditEntity.class, new DBParam[]{new DBParam("OPERATION_TYPE", type.name()), new DBParam("EVENT_OUTCOME", outcome.name()), new DBParam("SPACE_KEY", space != null ? space.getLowerKey() : null), new DBParam("GROUP_NAME", relatedGroupName), new DBParam("USER_NAME", relatedUserName), new DBParam("SUMMARY", summary), new DBParam("COMMENT", comment), new DBParam("CREATED_BY_USER_KEY", adminUser.getKey().getStringValue()), new DBParam("CREATED_BY_USER_NAME", adminUser.getName()), new DBParam("CREATED_DATE", new Timestamp(System.currentTimeMillis()))});
        return e;
    }

    public int deleteAuditEntities(Space space, int days) {
        int deleted = 0;
        Timestamp since = new Timestamp(System.currentTimeMillis() - TimeUnit.DAYS.toMillis((long) days));
        Query query = null;
        if (space != null) {
            query = Query.select().where("SPACE_KEY = ? AND CREATED_DATE < ?", new Object[]{space.getLowerKey(), since});
        } else {
            query = Query.select().where("CREATED_DATE < ?", new Object[]{since});
        }

        int count = this.fAo.count(AuditEntity.class, query);
        if (count > 0) {
            LOG.debug("Found " + count + " event records older than " + days + " to purge");
            Integer i = null;

            try {
                LOG.info("Deleting old audit events for space [" + space.getLowerKey() + "] using unquoted fields");
                i = this.fAo.deleteWithSQL(AuditEntity.class, "CREATED_DATE < ?", new Object[]{since});
            } catch (Exception var9) {
                LOG.info("That didnt work, so deleting old audit events for space [" + space.getLowerKey() + "] using quoted fields");
                i = this.fAo.deleteWithSQL(AuditEntity.class, "\"CREATED_DATE\" < ?", new Object[]{since});
            }

            if (i != null) {
                deleted = i;
                LOG.debug("Deleted " + deleted + " audit events for space: " + space.getLowerKey());
            }
        }

        return deleted;
    }

    public int deleteAllAuditEntities(int days) {
        int deleted = 0;
        Timestamp since = new Timestamp(System.currentTimeMillis() - TimeUnit.DAYS.toMillis((long) days));
        Query hintQuery = Query.select().where("CREATED_DATE < ?", new Object[]{since});
        int count = this.fAo.count(AuditEntity.class, hintQuery);
        if (count > 0) {
            Integer i = null;

            try {
                LOG.info("Deleting ALL old audit events using unquoted fields");
                i = this.fAo.deleteWithSQL(AuditEntity.class, "CREATED_DATE < ?", new Object[]{since});
            } catch (Exception var8) {
                LOG.info("That didnt work, so deleting ALL old audit events using quoted fields");
                i = this.fAo.deleteWithSQL(AuditEntity.class, "\"CREATED_DATE\" < ?", new Object[]{since});
            }

            if (i != null) {
                deleted = i;
                LOG.debug("Deleted " + deleted + " audit events over all spaces");
            }
        }

        return deleted;
    }

    public AuditEntity[] getAuditEvents(Space space, int days) {
        Timestamp since = new Timestamp(System.currentTimeMillis() - TimeUnit.DAYS.toMillis((long) days));
        Query query = null;
        if (space != null && space.getLowerKey() != null) {
            query = Query.select().where("SPACE_KEY = ? AND CREATED_DATE > ?", new Object[]{space.getLowerKey(), since}).order("CREATED_DATE DESC");
        } else {
            query = Query.select().where("CREATED_DATE > ?", new Object[]{since}).order("CREATED_DATE DESC");
        }

        AuditEntity[] ret = (AuditEntity[]) this.fAo.find(AuditEntity.class, query);
        if (ret.length == 0) {
            ret = null;
        }

        return ret;
    }


    public static enum OperationType {
        systemConfigUpdated,
        createUser,
        createGroup,
        createRemoteGroup,
        removeGroup,
        removeRemoteGroup,
        addUserToGroup,
        addUserToRemoteGroup,
        removeUserFromGroup,
        removeUserFromRemoteGroup;

        private OperationType() {
        }
    }

    public static enum AuditEventOutcome {
        success,
        error;

        private AuditEventOutcome() {
        }
    }
}
